package com.yunwaikeji.gy_tool_library.utils;

import android.os.Handler;

import java.util.Timer;
import java.util.TimerTask;

/**
 * 计时器
 */
public class GYTimerUtils {
    //开始时间
    private long startMillisecond = 0;
    //结束时间
    private long endMillisecond = 0;
    //当前时间
    private long nowMillisecond = 0;
    //精度，多久一次
    private long waitMillisecond = 100;
    //是否倒计时，false正计时，true倒计时
    private boolean isCountDown = false;

    /**
     * 获取开始毫秒
     *
     * @return
     */
    public long getStartMillisecond() {
        return startMillisecond;
    }

    /**
     * 获取开始秒
     *
     * @return
     */
    public long getStartSecond() {
        return startMillisecond / 1000;
    }

    /**
     * 设置开始毫秒
     *
     * @param startMillisecond
     * @return
     */
    public GYTimerUtils setStartMillisecond(long startMillisecond) {
        this.startMillisecond = startMillisecond;
        if (!isCountDown) {
            if (nowMillisecond < startMillisecond) {
                nowMillisecond = startMillisecond;
            }
        } else {
            if (nowMillisecond > startMillisecond) {
                nowMillisecond = startMillisecond;
            }
        }
        return this;
    }

    /**
     * 设置开始秒
     *
     * @param startSecond
     * @return
     */
    public GYTimerUtils setStartSecond(long startSecond) {
        setStartMillisecond(startSecond * 1000);
        return this;
    }


    /**
     * 获取结束毫秒
     *
     * @return
     */
    public long getEndMillisecond() {
        return endMillisecond;
    }

    /**
     * 获取结束时间
     *
     * @return
     */
    public long getEndSecond() {
        return endMillisecond / 1000;
    }

    /**
     * 设置结束毫秒
     *
     * @param endMillisecond
     * @return
     */
    public GYTimerUtils setEndMillisecond(long endMillisecond) {
        this.endMillisecond = endMillisecond;
        return this;
    }

    /**
     * 设置结束秒
     *
     * @param endSecond
     * @return
     */
    public GYTimerUtils setEndSecond(long endSecond) {
        setEndMillisecond(endSecond * 1000);
        return this;
    }

    /**
     * 获取当前毫秒
     *
     * @return
     */
    public long getNowMillisecond() {
        return nowMillisecond;
    }

    /**
     * 获取当前秒
     *
     * @return
     */
    public long getNowSecond() {
        return nowMillisecond / 1000;
    }

    /**
     * 设置当前毫秒
     *
     * @param nowMillisecond
     * @return
     */
    public GYTimerUtils setNowMillisecond(long nowMillisecond) {
        this.nowMillisecond = nowMillisecond;
        return this;
    }

    /**
     * 设置当前秒
     *
     * @param second
     * @return
     */
    public GYTimerUtils setNowSecond(long second) {
        setNowMillisecond(second * 1000);
        return this;
    }

    /**
     * 获取精度，多久变更一次
     *
     * @return
     */
    public long getWaitMillisecond() {
        return waitMillisecond;
    }

    /**
     * 设置精度，多久变更一次，默认100毫秒
     * 精度太小计时会不准确，100毫秒最佳
     *
     * @param waitMillisecond
     * @return
     */
    public GYTimerUtils setWaitMillisecond(long waitMillisecond) {
        this.waitMillisecond = waitMillisecond;
        return this;
    }

    /**
     * 监听
     *
     * @param onGYTimerListener
     * @return
     */
    public GYTimerUtils setOnGYTimerListener(OnGYTimerListener onGYTimerListener) {
        this.onGYTimerListener = onGYTimerListener;
        return this;
    }

    private boolean isTime = false;

    /**
     * 开始/继续
     */
    public void start() {
        if (!isTime) {
            showSecond = -1;
            isTime = true;
            isTiming = false;
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    time();
                }
            }, 0, waitMillisecond);
        }
    }

    /**
     * 重新开始
     */
    public void reStart() {
        showSecond = -1;
        nowMillisecond = startMillisecond;
        timer.cancel();
        isTiming = false;
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                time();
            }
        }, 0, waitMillisecond);
    }

    /**
     * 停止
     */
    public void stop() {
        showSecond = -1;
        nowMillisecond = startMillisecond;
//        now(nowMillisecond);
        isTime = false;
        timer.cancel();
    }

    /**
     * 暂停
     */
    public void pause() {
        isTime = false;
        timer.cancel();
    }

    /**
     * 设置是否倒计时
     *
     * @return
     */
    public GYTimerUtils setCountDown(boolean isCountDown) {
        this.isCountDown = isCountDown;
        return this;
    }

    /**
     * 获取是否倒计时
     *
     * @return
     */
    public boolean isCountDown() {
        return isCountDown;
    }

    private Timer timer = new Timer();
    private boolean isTiming = false;

    private void time() {
        if (!isTiming) {
            nowMillisecond = startMillisecond;
            isTiming = true;
        }
        now(nowMillisecond);
        if (!isCountDown) {
            if (startMillisecond >= endMillisecond || nowMillisecond >= endMillisecond) {
                over(nowMillisecond);
            } else {
                nowMillisecond += waitMillisecond;
            }
        } else {
            if (startMillisecond <= endMillisecond || nowMillisecond <= endMillisecond) {
                over(nowMillisecond);
            } else {
                nowMillisecond -= waitMillisecond;
            }
        }
    }

    private Handler handler = new Handler();

    private long showSecond = -1;

    private void now(long nowTime) {
        if (onGYTimerListener != null) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    long showTime = 0;
                    if (!isCountDown) {
                        //正计时
                        if (nowTime >= nowTime / 1000 * 1000) {
                            showTime = nowTime / 1000;
                        }
                    } else {
                        //倒计时
                        if (nowTime <= nowTime / 1000 * 1000 + 1000) {
                            showTime = nowTime / 1000 + 1;
                        }
                    }
                    if (showSecond != showTime) {
                        showSecond = showTime;
                        onGYTimerListener.onGYTimerSecond(showTime);
                    }
                    onGYTimerListener.onGYTimerMilliSecond(nowTime);
                }
            });
        }
    }

    private void over(long nowTime) {
        showSecond = -1;
        if (onGYTimerListener != null) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    onGYTimerListener.onGYTimerOver(nowTime / 1000, nowTime);
                    isTime = false;
                    timer.cancel();
                }
            });
        }
    }

    private OnGYTimerListener onGYTimerListener;

    public interface OnGYTimerListener {
        void onGYTimerSecond(long second);

        void onGYTimerMilliSecond(long millisecond);

        void onGYTimerOver(long second, long millisecond);
    }
}
